package collaboration.common;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.IOException;

import javax.swing.JComponent;

import collaboration.client.CollabClient;

/**
 * The <code>CollaborationApp</code> extends <code>JComponent</code> and 
 * contains all the methods necessary to implement a <code>CollaborationApp</code>.
 * All other applications must <code>extend</code> this method.
 * Note: This is used as the default blank application as a place holder.
 * 
 * @author Trevor Clack 6286191
 * @author Bowen Cheng 6204467
 * @version November 26, 2012 (1.40)
 */
public class CollaborationApp extends JComponent{

	//------------------------
	// MEMBER VARIABLES
	//------------------------

	/**
	 * A unique identifier for this application.
	 */
	public static final long serialVersionUID = -6365792224338173055L;

	/**
	 * The application's name.
	 */
	protected String applicationName;

	/**
	 * The index of this application.
	 */
	protected int index;

	/**
	 * A Boolean value to indicate if debug is on (true) or off (false).
	 */
	protected boolean debug;

	//collaborationApp Associations
	/**
	 * The instance of <code>CollabClient</code> for this <code>CollaborationApp</code>.
	 */
	private CollabClient thisCollabClient;

	//------------------------
	// CONSTRUCTOR
	//------------------------

	/**
	 * The <code>CollaborationApp</code> constructor.
	 * 
	 * @param aCollabClient The instance of <code>CollabClient</code> for this <code>CollaborationApp</code>.
	 * @param index The index for this instance of <code>CollaborationApp</code>.
	 * @throws A <code>RuntimeException</code> if it could not create this instance of <code>CollaborationApp</code>.
	 */
	public CollaborationApp(CollabClient aCollabClient, int index) throws RuntimeException
	{
		boolean didAddCollabClient = setCollabClient(aCollabClient);
		if (!didAddCollabClient)
		{
			throw new RuntimeException("Unable to create CollaborationApp due to CollabClient");
		}
		applicationName = "Collaboration Application";
		this.index = index;
		debug = thisCollabClient.getDebug();//debug is set same as the client
		setLayout(new GridLayout(1,1));
		setPreferredSize(new Dimension(300,300));
		setMinimumSize(new Dimension(100, 100));
		setToolTipText(applicationName + " " + (index + 1));
	}

	//------------------------
	// MEMBER FUNCTIONS
	//------------------------

	/**
	 * Hook method called if there is application communication incoming.
	 * This should be overridden if the application needs to receive messages. 
	 *
	 * @param msg The message to be received.
	 */
	public void handleMessageFromAppUI(StringBuffer msg){
		String message = msg.toString();
		if (message.startsWith("^")) { // All application commands should start with ^
			//This should be overridden if the application needs to receive messages
		}// ignore if the command is not properly formatted
	}

	/**
	 * Hook method called to return the applications <code>serialVersionUID</code>.
	 *
	 * @return The applications <code>serialVersionUID</code>.
	 */
	public long getUniqueID(){
		return serialVersionUID;
	}

	/**
	 * Hook method called to return the applications
	 * name.
	 *
	 * @return The applications name.
	 */
	public String getApplicationName(){
		return applicationName;
	}


	/**
	 * Sends a StringBuffer object to the server. This is the only way that
	 * applications should communicate with the server.
	 *
	 *  @param msg   The message to be sent.
	 *  @throws IOException The IOException thrown by this instance of <code>CollabClient</code>.
	 */
	final protected void sendToServer(StringBuffer msg) throws IOException
	{
		if(!(thisCollabClient==null)){
			thisCollabClient.sendToServer(msg);
		}
	}

	/**
	 * This method gets the current state of <code>debug</code>.
	 * Returns false if debug is off and true if debug is on.
	 * 
	 * @return The current state of <code>debug</code>.
	 */
	public boolean getDebug(){
		return debug;
	}

	/**
	 * This method sets the state of <code>debug</code>.
	 * Sets false if debug is off and true if debug is on.
	 * 
	 * @param debugOn The state of <code>debug</code> to set.
	 */
	public void setDebug(boolean debugOn){
		debug = debugOn;
	}

	/* Code from Umple - edited*/

	//------------------------
	// INTERFACE
	//------------------------

	/**
	 * This method gets the instance of <code>CollabClient</code>.
	 * 
	 * @return The instance of <code>CollabClient</code>.
	 */
	public CollabClient getCollabClient()
	{
		return thisCollabClient;
	}

	/**
	 * This method sets this instance of <code>CollabClient</code>.
	 * Returns true if the instance was set and false otherwise.
	 * 
	 * @param aCollabClient This instance of <code>CollabClient</code>.
	 * @return A boolean indicating true if the instance was set and false otherwise.
	 */
	public boolean setCollabClient(CollabClient aCollabClient)
	{
		boolean wasSet = false;
		//Must provide collabClient to collaborationApp
		if (aCollabClient == null)
		{
			return wasSet;
		}

		thisCollabClient = aCollabClient;
		wasSet = true;
		return wasSet;
	}

	/**
	 * This method deletes all the elements used by this instance of <code>CollaborationApp</code>.
	 */
	public void delete()
	{
		this.thisCollabClient = null;
	}
}
